import { goToDropPos } from "@/contrib/creep/harvester"
import { CreepConfig, CreepData, CreepRole } from "@/role/types/role"
import { repairSetting } from "@/setting"
import { serializePos } from "@/utils"
import { filter, min } from "lodash"
import room from "../room"
import { creepDefaultMemory } from "../spawn/constant"
import { GetName } from "../spawn/nameGetter"
import { roles } from "../spawn/spawnRoles"


interface RoomNumberSettings {
    [role: string]: number
}

interface NumberSettings {
    [room: string]: RoomNumberSettings
}

interface NumberReturn {
    creepsNum: number
    needSpawn: boolean
}


export default class CreepNumberSettings {

    static _data: NumberSettings

    /**
     *
     */
    static init(): void {

        roles

        CreepNumberSettings._data = {
            ['E35S49']: {
                [CreepRole.Processor]: 1,
                [CreepRole.Harvester]: 2,
                [CreepRole.TaskManager]: 2,
                [CreepRole.Worker]: 1,
                [CreepRole.WallerFiller]: 1,
                [CreepRole.CenterManager]: 1,
                // [CreepRole.Upgrader]: 0,
                [CreepRole.RemoteHarvester]: 2,
                [CreepRole.RemoteManager]: 4,
                [CreepRole.RemoteWorker]: 1,
                [CreepRole.Reserver]: 1,
            },
            ['E35S48']: {
                [CreepRole.Processor]: 1,
                [CreepRole.Harvester]: 2,
                // [CreepRole.TaskManager]: 1,
                [CreepRole.Worker]: 1,
                [CreepRole.Upgrader]: 3,
            },
            ['E39S52']: {
                [CreepRole.Processor]: 1,
                [CreepRole.Harvester]: 2,
                [CreepRole.TaskManager]: 2,
                [CreepRole.Worker]: 1,
                [CreepRole.CenterManager]: 1,
                [CreepRole.Upgrader]: 2,
                [CreepRole.RemoteHarvester]: 2,
                [CreepRole.RemoteManager]: 2,
                [CreepRole.RemoteWorker]: 1,
                [CreepRole.Reserver]: 1,
                [CreepRole.Attacker]: 1,
            },
            ['E45S48']: {
                [CreepRole.Processor]: 1,
                [CreepRole.Harvester]: 2,
                [CreepRole.TaskManager]: 2,
                [CreepRole.Worker]: 1,
                [CreepRole.WallerFiller]: 1,
                [CreepRole.Upgrader]: 2,
            }
        }
    }

    // static creepNumsCheck(creep: Creep): void {
    // }

    /**
     *
     * @param roomName
     * @param roleName
     * @returns
     */
    static spawnCheck(roomName: string, roleName: CreepRole): NumberReturn {
        const roomNumberSettings = CreepNumberSettings._data[roomName]
        if (!roomNumberSettings) {
            return null
        }
        if (!roomNumberSettings[roleName]) {
            return null
        }
        const num = roomNumberSettings[roleName]
        const creeps = _.filter(Memory.creeps, (creepMemory) => creepMemory.spawnRoom == roomName && creepMemory.role == roleName)
        // const creeps = _.filter(Game.creeps, (creep) => creep.memory.spawnRoom == roomName && creep.memory.role == roleName)
        const creepsNum = creeps.length
        if (creepsNum < num) {
            return {
                creepsNum: creepsNum,
                needSpawn: true
            }
        }
        return {
            creepsNum: creepsNum,
            needSpawn: false
        }
    }

    static getName(role: CreepRole, roomName: string, index: number): string {
        let name
        switch (role) {
            case CreepRole.TaskManager:
                name = GetName.taskManager(roomName, index)
                break
            case CreepRole.Harvester:
                name = GetName.harvester(roomName, index)
                break
            case CreepRole.Worker:
                name = GetName.worker(roomName, index)
                break
            case CreepRole.Manager:
                name = GetName.manager(roomName, index)
                break
            case CreepRole.RemoteManager:
                name = GetName.remoteManager(roomName, index)
                break
            case CreepRole.RemoteHarvester:
                name = GetName.remoteHarvester(roomName, index)
                break
            case CreepRole.WallerFiller:
                name = GetName.wallFiller(roomName, index)
                break
            case CreepRole.Upgrader:
                name = GetName.upgrader(roomName, index)
                break
            case CreepRole.Processor:
                name = GetName.processor(roomName, index)
                break
            // case CreepRole.Claimer:
            // break
            case CreepRole.CenterManager:
                name = GetName.centerManager(roomName, index)
                break
            case CreepRole.Reserver:
                name = GetName.reserver(roomName, index)
                break
            case CreepRole.Attacker:
                name = GetName.attacker(roomName, index)
                break
            case CreepRole.RemoteWorker:
                name = GetName.remoteWorker(roomName, index)
                break
            case CreepRole.CenterLabManager:
                name = GetName.centerLabManager(roomName, index)
                break
        }
        return name
    }

    static doSpawnCreep(spawn: StructureSpawn, role: CreepRole, data: CreepData): ScreepsReturnCode {
        let num: number = CreepNumberSettings._data[spawn.room.name][role]
        for (var i = 0; i < num + 1; i++) {
            if (!Game.creeps[CreepNumberSettings.getName(role, spawn.room.name, i)]) {
                num = i
                break
            }
        }
        const name = CreepNumberSettings.getName(role, spawn.room.name, num)
        if (!name) {
            return ERR_INVALID_ARGS
        }
        const creepWork: CreepConfig<CreepRole> = roles[role]
        const body: BodyPartConstant[] = creepWork.bodys(spawn.room, spawn, data)
        const memory: CreepMemory = { ...creepDefaultMemory, spawnRoom: spawn.room.name, role, data }
        return spawn.spawnCreep(body, name, { memory })
    }

    static runSpawnTask(spawn: StructureSpawn): void {
        //
        // // 本 tick creep 数量没变，不用执行检查
        // if (Object.keys(Memory.creeps || {}).length === Object.keys(Game.creeps).length) return

        // // 遍历所有 creep 内存，检查其是否存在
        // for (const name in Memory.creeps) {
        //     if (name in Game.creeps) continue

        //     // creep 的内存不可能完全为空，所以这里只有可能是 creep 主动释放（比如去了其他 shard）
        //     // 所以这里不予重生
        //     if (Object.keys(Memory.creeps[name]).length <= 0) {
        //         // console.log(name, '离开了', Game.shard.name)
        //         delete Memory.creeps[name]
        //         continue
        //     }

        //     const creepMemory = Memory.creeps[name]
        //     const { spawnRoom: spawnRoomName, data, role, cantRespawn } = creepMemory

        //     // 禁止孵化的 creep 直接移除
        //     if (cantRespawn) {
        //         // log(`死亡 ${creepName} 被禁止孵化，已删除`, 'creepController')
        //         delete Memory.creeps[name]
        //         return
        //     }

        //     // 没有找到目标孵化房间
        //     const spawnRoom = Game.rooms[spawnRoomName]
        //     if (!spawnRoom) {
        //         // log(`死亡 ${creepName} 未找到孵化房间 ${spawnRoomName}, 已删除`, 'creepController')
        //         delete Memory.creeps[name]
        //         return
        //     }

        //     const creepWork: CreepConfig<CreepRole> = roles[role]

        //     // 通过 isNeed 阶段判断该 creep 是否要继续孵化
        //     // 没有提供 isNeed 阶段的话则默认需要重新孵化
        //     // if (creepWork.isNeed && !creepWork.isNeed(spawnRoom, creepMemory, name)) {
        //     //     delete Memory.creeps[name]
        //     //     return
        //     // }

        //     // 加入生成，加入成功的话删除过期内存
        //     // const result = spawnRoom.spawner.addTask(name, role, data)

        //     const spawnTask: ISpawnTask = {
        //         type: TaskType.SPAWN,
        //         roomName: spawnRoom.name,
        //         taskType: SpawnTaskType.HARVESTER,
        //         status: TaskStatus.PENDING,
        //         name: name,
        //         role: role,
        //         data: data
        //     }
        //     const taskId: string = TaskController.addTask(spawnTask)
        //     Memory.waitSpawnCreeps[name] = spawnRoomName

        //     // if (result === ERR_NAME_EXISTS) log(`死亡 ${name} 孵化任务已存在`, 'creepController')
        //     delete Memory.creeps[name]
        // }
    }

    static doSpawnTask(): void {
        // const task: ISpawnTask = TaskController.getTask(TaskType.SPAWN) as ISpawnTask
        // if (task) {
        //     let name = task.name
        //     const role = task.role
        //     const data = task.data
        //     let num: number
        //     switch (task.taskType) {
        //         case SpawnTaskType.HARVESTER:
        //             num = harvesterNum as number
        //             for (var i = 0; i < num + 1; i++) {
        //                 if (!Game.creeps[GetName.harvester(spawn.room.name, i)]) {
        //                     num = i
        //                     name = GetName.harvester(spawn.room.name, num)
        //                     break
        //                 }
        //             }
        //             break
        //         case SpawnTaskType.MANAGER:
        //             num = managerNum as number
        //             for (var i = 0; i < num + 1; i++) {
        //                 if (!Game.creeps[GetName.manager(spawn.room.name, i)]) {
        //                     num = i
        //                     name = GetName.manager(spawn.room.name, num)
        //                     break
        //                 }
        //             }
        //             break
        //         case SpawnTaskType.WORKER:
        //             num = workerNum as number
        //             for (var i = 0; i < num + 1; i++) {
        //                 if (!Game.creeps[GetName.worker(spawn.room.name, i)]) {
        //                     num = i
        //                     name = GetName.worker(spawn.room.name, num)
        //                     break
        //                 }
        //             }
        //             break
        //         case SpawnTaskType.REMOTE_MANAGER:
        //             num = remoteManagerNum as number
        //             for (var i = 0; i < num + 1; i++) {
        //                 if (!Game.creeps[GetName.remoteManager(spawn.room.name, i)]) {
        //                     num = i
        //                     name = GetName.remoteManager(spawn.room.name, num)
        //                     break
        //                 }
        //             }
        //             break
        //     }
        //     const creepWork: CreepConfig<CreepRole> = roles[role]
        //     const body: BodyPartConstant[] = creepWork.bodys(spawn.room, spawn, data)
        //     const memory: CreepMemory = { ...creepDefaultMemory, spawnRoom: spawn.room.name, role, data }
        //     const status: ScreepsReturnCode = spawn.spawnCreep(body, name, { memory })
        //     // spawnCheck
        //     if (status == OK) {
        //         task.status = TaskStatus.STARTED
        //         log(`spawntask started`)
        //         delete Memory.tasks[task.type][task.id]
        //         return
        //     }
        // }
    }
}
